package com.easybuilder.core.im.netty.websocket;

import com.easybuilder.common.utils.StringUtil;
import com.easybuilder.common.utils.ThreadPoolUtil;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.concurrent.GlobalEventExecutor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
@Component
@Slf4j
public class WebsocketContext {

    /** 用户id与channelId映射关系（保存系统用户id与channelId的对应关系，当获取消息接收人通道时，可以根据接收人id获取到对应的channelId，再从channelMap中获取）*/
    private static final ConcurrentHashMap<Long, String> USERID_CHANNELID_MAP = new ConcurrentHashMap<>();

    /** 通道容器，真正保存通道的地方，通道id作为key，通道作为value */
    private static final ConcurrentHashMap<String, Channel> CHANNEL_MAP = new ConcurrentHashMap<>();

    /** 过期key清理锁 */
    private static final Object CLEAR_LOCK = new Object();
//
//    /** 添加用户通道关系锁 */
//    private static final Object ADD_CHANNEL_LOCK = new Object();

    /** 存放普通游客客户端channel */
    private static final ChannelGroup CHANNEL_GROUP = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

    /** 存放系统用户与通道的对应关系 */
    private static final ConcurrentHashMap<Long, Channel> USER_CHANNEL_MAP = new ConcurrentHashMap<>();

    /** 添加游客通道 */
    public static void addVisitorChannel(Channel channel) {
        // 保存通道
        CHANNEL_MAP.put(channel.id().asLongText(), channel); 
    }

    /** 添加用户通道 */
    public static void addUserChannel(Long userId, Channel channel) {
        // 保存通道
        CHANNEL_MAP.put(channel.id().asLongText(), channel);
        // 等待添加用户通道锁释放后，执行内部方法
        synchronized (CLEAR_LOCK) {
            // 保存用户id与通道id的对应关系
            USERID_CHANNELID_MAP.put(userId, channel.id().asLongText());
            CLEAR_LOCK.notify();
        }
    }

    /** 获取系统用户通道 */
    public static Channel getUserChannel(Long userId) {
        // 根据用户id获取对应通道id
        String channelId = USERID_CHANNELID_MAP.get(userId);
        if (StringUtil.isNotEmpty(channelId)) {
            // 从通道容器中根据id获取通道
            return CHANNEL_MAP.get(channelId);
        }
        return null;
    }

    /** 获取游客通道 */
    public static Channel getVisitorChannel(Channel channel) {
        String channelId = channel.id().asLongText();
        return CHANNEL_MAP.get(channelId);
    }

    /** 移除游客通道 */
    public static void removeVisitor(Channel channel) {
        System.out.println("移除通道，暂时不做处理");
        // 将通道从容器中移除
        Channel remove = CHANNEL_MAP.remove(channel.id().asLongText());
        // 将用户id与通道id的映射关系移除
        if (remove != null) {
            String channelId = remove.id().asLongText();
            for (Long userId : USERID_CHANNELID_MAP.keySet()) {
                if (channelId.equals(USERID_CHANNELID_MAP.get(userId))){
                    USERID_CHANNELID_MAP.remove(userId);
                }
            }
        }
    }

    /** 移除系统用户通道 */
    public static void removeUserChannel(Long userId) {
        // 移除通道
        CHANNEL_MAP.remove(userId);
        // 移除用户通道对应关系
        USERID_CHANNELID_MAP.remove(userId);
    }


}
